package org.linlinjava.litemall.db.service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import javax.annotation.Resource;
import org.linlinjava.litemall.db.dao.LitemallAccountMapper;
import org.linlinjava.litemall.db.domain.LitemallAccount;
import org.linlinjava.litemall.db.domain.LitemallAccountExample;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import com.github.pagehelper.PageHelper;

@Service
public class LitemallAccountService {

  @Resource
  private LitemallAccountMapper accountMapper;

  @Resource
  private LitemallAccountLogService accountLogService;

  public LitemallAccount findById(Integer accountId) {
    return accountMapper.selectByPrimaryKey(accountId);
  }

  private void update(LitemallAccount account) {
    account.setUpdateTime(LocalDateTime.now());
    accountMapper.updateByPrimaryKeySelective(account);
  }

  @Transactional
  public LitemallAccount add(String username) {
    LitemallAccount account = new LitemallAccount();
    account.setUpdateTime(LocalDateTime.now());
    account.setBalance(new BigDecimal(0));
    account.setBlock(false);
    account.setUsername(username);
    accountMapper.insertSelective(account);
    return account;
  }

  @Transactional
  void withdraw(Integer accountId, String orderNo, BigDecimal amount) {
    LitemallAccount account = findById(accountId);
    if (account.getBalance().compareTo(amount) < 0) {
      throw new RuntimeException("账号余额不足");
    }
    account.setBalance(account.getBalance().subtract(amount));
    update(account);
    accountLogService.withdraw(accountId, "", orderNo, amount, account.getBalance());
  }

  @Transactional
  void recharge(//
      Integer accountId, String remark, String orderNo, BigDecimal amount//
  ) {
    LitemallAccount account = findById(accountId);
    account.setBalance(account.getBalance().add(amount));
    update(account);
    accountLogService.recharge(accountId, remark, orderNo, amount, account.getBalance());
  }

  @Transactional
  void consume(//
      Integer accountId, String remark, String orderNo, BigDecimal amount//
  ) {
    LitemallAccount account = findById(accountId);
    if (account.getBalance().compareTo(amount) < 0) {
      throw new RuntimeException("账号余额不足");
    }
    account.setBalance(account.getBalance().subtract(amount));
    update(account);
    accountLogService.withdraw(accountId, remark, orderNo, amount, account.getBalance());
  }

  @Transactional
  void refund(//
      Integer accountId, String remark, String orderNo, BigDecimal amount//
  ) {
    LitemallAccount account = findById(accountId);
    account.setBalance(account.getBalance().add(amount));
    update(account);
    accountLogService.recharge(accountId, remark, orderNo, amount, account.getBalance());
  }


  public List<LitemallAccount> querySelective(String username, Integer page, Integer size,
      String sort, String order) {
    LitemallAccountExample example = new LitemallAccountExample();
    LitemallAccountExample.Criteria criteria = example.createCriteria();

    if (!StringUtils.isEmpty(username)) {
      criteria.andUsernameLike("%" + username + "%");
    }

    if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
      example.setOrderByClause(sort + " " + order);
    }

    PageHelper.startPage(page, size);
    return accountMapper.selectByExample(example);
  }
}
